import { useUserStore } from '@/store/user';
import type {
   HttpError,
   HttpRequestConfig,
   HttpResponse,
} from '@toothdy/uvui-ts/libs/luch-request';

// 定义 Token 刷新响应的接口
interface TokenRefreshResponse {
   token: string;
   refreshToken: string;
}

// 定义类型别名
type RequestCallback = () => void;
type RequestTask = Array<RequestCallback>;

export default (): void => {
   uni.$uv.http.setConfig((config: HttpRequestConfig): HttpRequestConfig => {
      config.baseURL = 'https://v2.xxapi.cn/api';
      return config;
   });

   // 请求列队
   const requestTaks: RequestTask = [];
   // 是否正在刷新Token
   let isRefreshToken = false;

   // 请求拦截
   uni.$uv.http.interceptors.request.use(
      (config: HttpRequestConfig): HttpRequestConfig => {
         const { getToken } = useUserStore();

         config.data = config.data || {};
         config.header!.Authorization = `Bearer ${getToken?.token}`;
         return config;
      },
      (error: HttpError) => {
         return Promise.reject(error);
      }
   );

   // 响应拦截
   uni.$uv.http.interceptors.response.use(
      (response: HttpResponse): Promise<HttpResponse> => {
         if (response.data?.code === 200) {
            return response.data;
         }
         // 显示错误信息
         uni.$uv.toast(response.data?.message || '请求失败');
         return Promise.reject(response.data);
      },
      async (error: HttpError): Promise<HttpError> => {
         // 验证失败
         if (error.statusCode === 401) {
            return await handleTokenRefresh(error);
         }

         uni.$uv.toast(error.data?.message || '服务器异常');
         return Promise.reject(error);
      }
   );

   // 处理 Token 刷新
   async function handleTokenRefresh(error: HttpError): Promise<HttpError> {
      if (isRefreshToken) {
         // 如果正在刷新，将请求加入队列
         return new Promise(resolve => {
            requestTaks.push(() => {
               resolve(uni.$uv.http.request(error.config));
            });
         });
      }

      // 设置刷新状态
      isRefreshToken = true;

      try {
         const { getToken, setToken } = useUserStore();

         // 如果没有刷新Token
         if (!getToken?.refreshToken) {
            isRefreshToken = false;
            handleUnauthorized(error.data!);
            return Promise.reject(error);
         }

         // 刷新Token
         const refreshResponse = await uni.$uv.http.post<TokenRefreshResponse>(
            '/user/user/refreshToken',
            {
               refreshToken: getToken.refreshToken,
            }
         );

         // 设置Token
         setToken(refreshResponse.data);

         // 执行队列中的请求
         requestTaks.forEach(callback => callback());
         // 重新发起原始请求
         return uni.$uv.http.request(error.config);
      } catch (err) {
         // 刷新失败，执行队列中的请求
         requestTaks.forEach(callback => callback());

         // 延迟后跳转登录
         await uni.$uv.sleep(1000);
         handleUnauthorized(error.data!);
         return Promise.reject(error);
      } finally {
         // 清空队列并重置状态
         requestTaks.length = 0;
         isRefreshToken = false;
      }
   }

   // 处理认证失败
   function handleUnauthorized(error: HttpError): void {
      uni.showModal({
         title: '系统提示',
         content: '登录已过期，请重新登录',
         success: (res: UniApp.ShowModalRes) => {
            if (res.confirm) {
               // 清除登录状态
               const { logout } = useUserStore();
               logout();
               // 跳转登录页
               uni.navigateTo({
                  url: '/pages/login/login',
               });
            }
         },
      });
   }
};
